using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

using System.Net.Sockets;
using System.Net;

namespace TcpServer
{
    class Program
    {
        static void Main(string[] args)
        {
            FileStream fileout = null;
            //StreamWriter fileLog = null;

            databaseManagement database = new databaseManagement();

            /*
             * setDatabasePathAndDatabaseName(string databasePath, string databaseName)
             */
            database.setDatabasePathAndDatabaseName(".", "DB_Log");

            try
            {
                int port = 2000;
                string host = "127.0.0.1";
                IPAddress ip = IPAddress.Parse(host);
                IPEndPoint ipe = new IPEndPoint(ip, port);
                Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                s.Bind(ipe);
                s.Listen(0);

                Socket temp = null;

                while (true)
                {
                    Console.WriteLine("Wait for connect");
                    temp = s.Accept();
                    Console.WriteLine("Socket Get a connect");

                    byte[] recvBytes = new byte[10240];
                    //byte[] status = new byte[1024];
                    int bytes;
                    string recvStr = "";
                    //string logFile = "transfer.log";
                    long file_size = 0;
                    long file_write = 0;

                    while (true)
                    {
                        //fileLog = new StreamWriter (logFile,true);
                        
                        bytes = temp.Receive(recvBytes, recvBytes.Length, 0);

                        recvStr = Encoding.UTF8.GetString(recvBytes, 0, bytes);
                        Console.Write("server Get Message:{0}", recvStr);
                        if (recvStr.Substring(0, 8).Equals("Initial:"))
                        {
                            // get file name
                            recvStr = recvStr.Substring(8);
                            Console.WriteLine(" : "+ recvStr);
                            if (File.Exists(recvStr))
                            {
                                fileout = new FileStream(recvStr, FileMode.CreateNew | FileMode.Truncate, FileAccess.Write);
                            }
                            else
                            {
                                fileout = new FileStream(recvStr, FileMode.CreateNew, FileAccess.Write);
                            }
                            
                            //fileLog.Write("Create:"+recvStr+":");    
                            temp.Send(recvBytes, bytes, 0);
                            System.Threading.Thread.Sleep(50);
                        }
                        else
                        {   
                            temp.Send(Encoding.UTF8.GetBytes("Failed"), recvStr.Length, 0);
                            
                            System.Threading.Thread.Sleep(40);
                            break;
                        }
                        //size
                        string fileName = recvStr;
                        bytes = temp.Receive(recvBytes, recvBytes.Length, 0);
                        recvStr = Encoding.UTF8.GetString(recvBytes, 0, bytes);
                        
                        //fileLog.WriteLine(recvStr+":");

                        temp.Send(recvBytes, bytes, 0);
                        System.Threading.Thread.Sleep(50);
                        file_size = Convert.ToInt64(recvStr);
                        file_write = 0;

                        /*
                         * insertNewData(string fileName , int fileSize)
                         */
                        database.insertNewData(fileName, (int)file_size);

                        while (true)
                        {
                            bytes = temp.Receive(recvBytes, recvBytes.Length, 0);
                            if (bytes < 7)
                            {
                                recvStr = Encoding.UTF8.GetString(recvBytes, 0, bytes);
                                //if (recvStr.Equals("FinIsh"))
                                //{
                                //    fileLog.WriteLine("");
                                //    fileLog.WriteLine("Finish:"+file_write.ToString()+":");
                                //}
                                break;
                            }
                            Console.Write(".");

                            fileout.Write(recvBytes, 0, bytes);
                            //fileLog.Write((bytes%10240).ToString()+":");
                            
                            file_write += (long)bytes;

                            /*
                             * updateFinish(long ReceiveSize)
                             */
                            database.updateFinish(file_write);

                            byte[] status = Encoding.UTF8.GetBytes(bytes.ToString());
                            
                            temp.Send(status, status.Length, 0);
                            System.Threading.Thread.Sleep(10);

                        }
                        fileout.Close();
                        //fileLog.Close();
                     //   if (recvStr.Equals("FinIsh"))
                     //       break;
                    }
                }
                temp.Close();
                s.Close();
            }
            catch (ArgumentNullException e)
            {
                Console.WriteLine("ArgumentNullException: {0}", e);
            }
            catch (SocketException e)
            {
                Console.WriteLine("SocketException: {0}", e);
                fileout.Close();
                //fileLog.Close();
            }
        }
    }
}
